#include "ST7920.h"
unsigned int Local_Code[8][64];
void send_com(unsigned char cmd)
{
    chk_busy();
    CLRB(CONTROL,RS);  //RS = 0;
    CLRB(CONTROL,RW);  //RW = 0;
    asm volatile ("NOP");
    DATA = cmd;
    asm volatile ("NOP");
    enable;
}
void send_data(unsigned char dat)
{
   chk_busy();
    SETB(CONTROL,RS);  //RS = 1;
    CLRB(CONTROL,RW); //RW = 0;
    DATA = dat;
    asm volatile ("NOP");
    enable;
}
void chk_busy(void)
{
  	DATA = 0xff;
  	DATA_DDR=0x00;
  	CLRB(CONTROL,RS);
  	SETB(CONTROL,RW);
  	SETB(CONTROL,E);
  	 while ( DATA_IN & ( 1<<busy ) ) ;
  	CLRB(CONTROL,E);
  	DATA_DDR=0xFF;
}
void lcd_init()
{
    SETB(CONTROL,RST);
    SETB(CONTROL,PSB);
    send_com(0x30);
    sleep(50);
    send_com(0x0C);
    sleep(2);
    send_com(0x01);
    sleep(2);
    send_com(0x06);
    Local_Code_Clear();
   }
void set_xy(unsigned char xpos,unsigned char ypos)
{
    switch(ypos)
    {
    case 1:
        send_com(0X80|xpos);
        break;
    case 2:
        send_com(0X90|xpos);
        break;
    case 3:
        send_com(0X88|xpos);
        break;
    case 4:
        send_com(0X98|xpos);
        break;
    default:
        break;
    }

}
void print(unsigned char x,unsigned char y,char* str)
{
    unsigned char lcd_temp;
    set_xy(x,y);
    lcd_temp=*str;
    while(lcd_temp != 0x00)
    {
        send_data(lcd_temp);
        lcd_temp=*(++str);
    }
}
void printstr(unsigned char x,unsigned char y,unsigned char str[],unsigned char k)
{
    unsigned char n;
    switch (y)
    {
    case 1:
        x |= 0x80;
        break;
    case 2:
        x |= 0x90;
        break;
    case 3:
        x |= 0x88;
        break;
    case 4:
        x |= 0x98;
        break;
    default:
        break;
    }
    send_com(x);
    for(n=0; n < k; n++)
    {
        send_data(str[n]);
    }
}
void clr_lcd(void)
{
    send_com(0x01);

}
void Cursor_turn()
{
    send_com(0x30);
    send_com(0x0d);
}
void Cursor_OFF()
{
    send_com(0x30);
    send_com(0x0c);
}
void Cursor_ON()
{
    send_com(0x30);
    send_com(0x0e);
}
void PutBMP(unsigned char *graphic)
{
     unsigned char x, y;
    for(y = 0; y < 64; y++)
    {
        if(y < 32)
        {
            for(x = 0; x < 8; x++)
            {

                send_com(0x80 | y);
                send_com(0x80 | x);
                send_data(pgm_read_byte(&graphic[2*x + 16*y]));
                send_data(pgm_read_byte(&graphic[2*x+1 + 16*y]));
            }
        }
        else
        {
            for(x = 0; x < 8; x++)
            {

                send_com(0x80 | (y-32));
                send_com(0x88 | x);
                send_data(pgm_read_byte(&graphic[2*x + 16*y]));
                send_data(pgm_read_byte(&graphic[2*x+1 + 16*y]));
            }
        }

    }
}
void ClearGraphics()
{

unsigned char x, y;
    for(y = 0; y < 64; y++)
    {
        if(y < 32)
        {
            send_com(0x80 | y);
            send_com(0x80);
        }
        else
        {
            send_com(0x80 | (y-32));
            send_com(0x88);
        }
        for(x = 0; x < 8; x++)
        {
            send_data(0x00);
            send_data(0x00);
        }
    }
}
void Graphic_ON(){
    send_com(0x34);
    send_com(0x36);
}
void Graphic_OFF(){
    send_com(0x30);
}
void X_Straight_Line(unsigned char line)
{
	unsigned char i,j;
	j=line;
	for(i=0;i<128;i++)
    Draw_Dot(i,j);
}
void Draw_Dot(unsigned char X,unsigned char Y)
{
	unsigned int x_1=0,y_1=0,Row,Column;
	unsigned char H_data,L_data,move_bit;
	unsigned int D_data;
	Column = X/16;
	Row = Y;
	if(Row<16)
	{x_1=0x80;y_1=Row;}
	if((Row>=16)&&(Row<32))
	  {x_1=0x90;y_1=Row;}
	if((Row>=32)&&(Row<48))
	  {x_1=0x88;y_1=Row-32;}
	if( Row>=48 )
		{x_1=0x98;y_1=Row-32;}
	move_bit = X%16;
	D_data=(0x8000)>>move_bit;
    D_data=D_data |Local_Code[Column][Row];
   Local_Code[Column][Row]=D_data;
    H_data=D_data/256;
    L_data=D_data%256;
    send_com(0x34);
     send_com(0x80+y_1);
     send_com(x_1+Column);
     send_com(0x30);
    send_data(H_data);
    send_data(L_data);
     send_com(0x36);

}
void Draw_Rectangle(unsigned char x, unsigned char y, unsigned char a, unsigned char b)
{
  unsigned char j;
Local_Code_Clear();
  for (j = 0; j < a; j++) {
		Draw_Dot(x, y + j);
		Draw_Dot(x + b - 1, y + j);
	}
  for (j = 0; j < b; j++)	{
		Draw_Dot(x + j, y);
		Draw_Dot(x + j, y + a - 1);
	}
}
void Draw_Circle(unsigned char  xcenter, unsigned char  ycenter, unsigned char radius)
{


  Local_Code_Clear();

  int tswitch, y, x = 0;
  unsigned char d;

  d = ycenter - xcenter;
  y = radius;
  tswitch = 3 - 2 * radius;
  while (x <= y) {
    Draw_Dot(xcenter + x, ycenter + y);
    Draw_Dot(xcenter + x, ycenter - y);
    Draw_Dot(xcenter - x, ycenter + y);
    Draw_Dot(xcenter - x, ycenter - y);
    Draw_Dot(ycenter + y - d, ycenter + x);
    Draw_Dot(ycenter + y - d, ycenter - x);
    Draw_Dot(ycenter - y - d, ycenter + x);
    Draw_Dot(ycenter - y - d, ycenter - x);

    if (tswitch < 0) tswitch += (4 * x + 6);
    else {
      tswitch += (4 * (x - y) + 10);
      y--;
    }
    x++;
  }
}

void Local_Code_Clear()
{
	unsigned char i,j;
	for(i=0;i<8;i++)
		for(j=0;j<64;j++)
			Local_Code[i][j]=0;

}
